//
//  StepsChartVC.swift
//  TimeBoat
//
//  Created by bo wang on 2022/8/26.
//  Copyright © 2022 Time Boat. All rights reserved.
//

import UIKit
import Charts

class StepsChartVC: ChartsContentsVC {
    
    @IBOutlet var averageView: UIView?
    @IBOutlet var averageTitleLabel: UILabel?
    @IBOutlet var averageLabel: UILabel?
    @IBOutlet var totalView: UIView?
    @IBOutlet var totalTitleLabel: UILabel?
    @IBOutlet var totalLabel: UILabel?

    override var yValGranularitie: Double? { 100 }
    override var xValGranularitie: Double? {
        switch granularitie {
        case .day: return 1.0 / 24.0
        case .week, .month, .year, .none: return 1
        }
    }
    override var xValRange: ClosedRange<Double>? {
        switch granularitie {
        case .day: return -0.5...24.5
        case .week: return 1.5...8.5
        case .month: return 0.5...31.5
        case .year: return 0.5...12.5
        case .none: return 0...0
        }
    }
    override var chartViewType: ChartViewType {
        switch granularitie {
        case .day, .month: return .line
        case .week, .year: return .bar
        case .none: return .line
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        averageView?.isHidden = granularitie == .day
        totalView?.isHidden = false
    }
    
    override func loadChartView() {
        super.loadChartView()
        
        switch granularitie {
        case .day:
            break
        case .week:
            chartView?.xAxis.labelCount = 7
        case .month:
            break
        case .year:
            chartView?.xAxis.labelCount = 12
        case .none: break
        }
    }

    override func loadDayData(_ date: Date) {
        API.getStepsData(date, .day, imei: imei) { [weak self] result in
            guard result.suc, let data = result.data else {
                self?.onLoadDataFailed(result.errDesc)
                return
            }
            self?.onLoadSummaryData(data.info)
            
            let entries = data.list.compactMap { unit -> ChartDataEntry? in
                guard let hour = unit.hour else { return nil }
                return ChartDataEntry(x: hour, y: Double(unit.stepCount), data: unit)
            }
            self?.didLoadDayData(entries)
        }
    }
    
    override func loadWeekData(_ date: Date) {
        API.getStepsData(date, .week, imei: imei) { [weak self] result in
            guard result.suc, let data = result.data else {
                self?.onLoadDataFailed(result.errDesc)
                return
            }
            self?.onLoadSummaryData(data.info)
            
            let entries = data.list.compactMap { unit -> BarChartDataEntry? in
                guard let weekday = unit.weekday else { return nil }
                return BarChartDataEntry(x: Double(weekday), y: Double(unit.stepCount), data: unit)
            }
            self?.didLoadWeekData(entries)
        }
    }
    
    override func loadMonthData(_ date: Date) {
        API.getStepsData(date, .month, imei: imei) { [weak self] result in
            guard result.suc, let data = result.data else {
                self?.onLoadDataFailed(result.errDesc)
                return
            }
            self?.onLoadSummaryData(data.info)
            
            let entries = data.list.compactMap { unit -> ChartDataEntry? in
                guard let day = unit.day else { return nil }
                return ChartDataEntry(x: Double(day), y: Double(unit.stepCount), data: unit)
            }
            self?.didLoadMonthData(entries)
        }
    }
    
    override func loadYearData(_ date: Date) {
        API.getStepsYearlyData(date, imei: imei) { [weak self] result in
            guard result.suc, let data = result.data else {
                self?.onLoadDataFailed(result.errDesc)
                return
            }
            self?.onLoadSummaryData(data.info)
            
            let entries = data.list.compactMap { unit -> BarChartDataEntry? in
                guard unit.month > 0 else { return nil }
                return BarChartDataEntry(x: Double(unit.month), y: Double(unit.totalStepCount), data: unit)
            }
            self?.didLoadYearData(entries)
        }
    }
    
    func barWidth() -> CGFloat {
        if let viewWidth = chartView?.contentRect.width {
            let desWidth: CGFloat = 8
            switch granularitie {
            case .day: return 1
            case .week: return desWidth / (viewWidth / 7)
            case .month: return 1
            case .year: return desWidth / (viewWidth / 12)
            case .none: return 1
            }
        }
        return 0.5
    }
    
    func didLoadDayData(_ entries: [ChartDataEntry]) {
        guard !entries.isEmpty else {
            reloadChartView(data: nil)
            return
        }
        let dataSet = NormalLineChartDataSet(entries: entries)
        if entries.count == 1 {
            // 只有一个数据的时候显示圆圈
            dataSet.setupShowCircleDot()
        }
        reloadChartView(data: LineChartData(dataSet: dataSet))
    }
    
    func didLoadWeekData(_ entries: [BarChartDataEntry]) {
        guard !entries.isEmpty else {
            reloadChartView(data: nil)
            return
        }
        let dataSet = NormalBarChartDataSet(entries: entries)
        let chartData = BarChartData(dataSet: dataSet)
        chartData.barWidth = barWidth()
        reloadChartView(data: chartData)
    }
    
    func didLoadMonthData(_ entries: [ChartDataEntry]) {
        guard !entries.isEmpty else {
            reloadChartView(data: nil)
            return
        }
        let dataSet = NormalLineChartDataSet(entries: entries)
        if entries.count == 1 {
            // 只有一个数据的时候显示圆圈
            dataSet.setupShowCircleDot()
        }
        reloadChartView(data: LineChartData(dataSet: dataSet))
    }
    
    func didLoadYearData(_ entries: [BarChartDataEntry]) {
        guard !entries.isEmpty else {
            reloadChartView(data: nil)
            return
        }
        let dataSet = NormalBarChartDataSet(entries: entries)
        let chartData = BarChartData(dataSet: dataSet)
        chartData.barWidth = barWidth()
        reloadChartView(data: chartData)
    }
    
    func onLoadSummaryData(_ info: ChartSummaryInfoModel?) {
        totalLabel?.text = info?.totalStepCount.string
        averageLabel?.text = info?.averageStepCount.string
    }
    
    override func onLoadDataFailed(_ errDesc: String) {
        super.onLoadDataFailed(errDesc)
        totalLabel?.text = "--"
        averageLabel?.text = "--"
    }
}
